/*
 * @Author: yuki
 * @Date: 2025-10-25 16:42:41
 * @LastEditTime: 2025-11-06 19:50:21
 * @Description: 登陆注册服务
 */
import { Auth } from '@horoscope/shared';
import { Injectable, ServiceUnavailableException } from '@nestjs/common';

import { DataMismatchException } from '@/exception';
import { BcryptService } from '@/share/bcrypt.service';
import { PrismaService } from '@/share/prisma.service';
import { SnowflakeService } from '@/share/snowflake.service';
import { TokenService } from '@/share/token.service';
import { UserService } from '@/user/user.service';

import { RegisterDto, LoginDto } from './dto/auth.dto';

@Injectable()
export class AuthService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly snowflakeService: SnowflakeService,
    private readonly bcryptService: BcryptService,
    private readonly tokenService: TokenService,
    private readonly userService: UserService
  ) {}
  async register(data: RegisterDto): Promise<Auth.IRegisterResponse> {
    const user = await this.userService.checkUserExistsByUsername(
      data.username ?? data.email!
    );
    if (user) {
      throw new DataMismatchException('用户名或者邮箱已存在');
    }
    try {
      // 校验用户名或邮箱是否已存在
      const { password } = data;
      // 密码加密
      const hashedPassword = await this.bcryptService.hashPassword(password);
      const newUser = await this.prisma.user.create({
        data: {
          userName: data.username ?? data.email!,
          password: hashedPassword,
          email: data.email!,
          userId: this.snowflakeService.generate()
        }
      });
      return {
        userId: newUser.userId.toString(),
        userName: newUser.userName,
        email: newUser.email
      };
    } catch (error) {
      throw new ServiceUnavailableException(error.message);
    }
  }

  async login(data: LoginDto): Promise<Auth.ILoginResponse> {
    const { username, password } = data;
    const user = await this.prisma.user.findFirst({
      where: {
        OR: [{ userName: username }, { email: username }]
      }
    });
    if (!user) {
      throw new DataMismatchException('用户不存在');
    }
    const isPasswordValid = await this.bcryptService.verifyPassword(
      password,
      user.password
    );
    if (!isPasswordValid) {
      throw new DataMismatchException('密码错误');
    }
    return {
      token: this.tokenService.generateAccessToken({
        sub: user.id.toString(),
        userId: user.userId.toString(),
        username: user.userName
      }),
      userInfo: this.userService.formatUserInfo(user)
    };
  }
}
